package com.hj.lib.tio;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.hj.lib.entity.AjaxJson;
import com.hj.lib.entity.HjPacket;
import com.hj.lib.util.HjTioUtil;
import com.hj.lib.util.LogUtil;
import org.tio.client.intf.ClientAioHandler;
import org.tio.core.ChannelContext;
import org.tio.core.GroupContext;
import org.tio.core.Tio;
import org.tio.core.exception.AioDecodeException;
import org.tio.core.intf.Packet;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;

import static com.hj.lib.util.HjTioUtil.hjTioHandle;


public class HjClientAioHandler implements ClientAioHandler {

//	public static String TZRH_CMD = "D:\\Program Files (x86)\\HJMeeting\\run.exe ";
	public static String TZRH_CMD = "C:\\HJMeeting\\run.exe";
	public static String FQQM_CMD = "C:\\qm\\bundles\\qm\\qm.exe";
//	public static String FQQM_CMD = "D:\\dyz\\project\\git\\qm\\classes\\artifacts\\qm\\bundles\\qm\\qm.exe ";
	private static HjPacket heartbeatPacket = new HjPacket();
	public  static boolean isServer = false;
	/**
	 * 解码：把接收到的ByteBuffer，解码成应用可以识别的业务消息包
	 * 总的消息结构：消息头 + 消息体
	 * 消息头结构：    4个字节，存储消息体的长度
	 * 消息体结构：   对象的json串的byte[]
	 */
	public HjPacket decode(ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext) throws AioDecodeException {
		//收到的数据组不了业务包，则返回null以告诉框架数据不够
		if (readableLength < HjPacket.HEADER_LENGHT) {
			return null;
		}
		//读取消息体的长度
		int bodyLength = buffer.getInt();
		//数据不正确，则抛出AioDecodeException异常
		if (bodyLength < 0) {
			throw new AioDecodeException("bodyLength [" + bodyLength + "] is not right, remote:" + channelContext.getClientNode());
		}
		//计算本次需要的数据长度
		int neededLength = HjPacket.HEADER_LENGHT + bodyLength;
		//收到的数据是否足够组包
		int isDataEnough = readableLength - neededLength;
		// 不够消息体长度(剩下的buffe组不了消息体)
		if (isDataEnough < 0) {
			return null;
		} else //组包成功
		{
			HjPacket imPacket = new HjPacket();
			if (bodyLength > 0) {
				byte[] dst = new byte[bodyLength];
				buffer.get(dst);
				imPacket.setBody(dst);
			}
			return imPacket;
		}
	}
	/**
	 * 编码：把业务消息包编码为可以发送的ByteBuffer
	 * 总的消息结构：消息头 + 消息体
	 * 消息头结构：    4个字节，存储消息体的长度
	 * 消息体结构：   对象的json串的byte[]
	 */
	public ByteBuffer encode(Packet packet, GroupContext groupContext, ChannelContext channelContext) {
		HjPacket HjPacket = (HjPacket) packet;
		byte[] body = HjPacket.getBody();
		int bodyLen = 0;
		if (body != null) {
			bodyLen = body.length;
		}
		//bytebuffer的总长度是 = 消息头的长度 + 消息体的长度
		int allLen = HjPacket.HEADER_LENGHT + bodyLen;
		//创建一个新的bytebuffer
		ByteBuffer buffer = ByteBuffer.allocate(allLen);
		//设置字节序
		buffer.order(groupContext.getByteOrder());
		//写入消息头----消息头的内容就是消息体的长度
		buffer.putInt(bodyLen);
		//写入消息体
		if (body != null) {
			buffer.put(body);
		}
		return buffer;
	}
	/**
	 * 处理消息
	 */

	public void handler(Packet packet, ChannelContext channelContext) throws Exception {
		HjPacket HjPacket = (HjPacket) packet;
		byte[] body = HjPacket.getBody();
		if (body != null) {
			String str = new String(body, HjPacket.CHARSET);
			if (StrUtil.isNotBlank(str)) {
				LogUtil.debug("hjcommonlib",str);
				AjaxJson ajaxJson = JSON.parseObject(str,AjaxJson.class );
				try {
					if (ajaxJson.getCode() == AjaxJson.HjTioCode.TZRH) {
						Thread.sleep(2000);
						if ("isServer".equals(ajaxJson.getMsg())) {
							isServer = true;
						}
						String[] command = { TZRH_CMD, ajaxJson.getObj().toString()};
						Runtime.getRuntime().exec(command );
					}else if (ajaxJson.getCode() == AjaxJson.HjTioCode.RegDev) {
						ajaxJson.setCode(AjaxJson.HjTioCode.RegDev);
						HjTioUtil.send(ajaxJson);
					}
					else if (ajaxJson.getCode() == AjaxJson.HjTioCode.CQSB) {
						Runtime.getRuntime().exec("shutdown -r -t 0");
					}
				} catch (Exception e) {
					e.printStackTrace();

				}


				if (hjTioHandle != null) {
					hjTioHandle.onMessage(ajaxJson);
				}
			}
		}
		return;
	}
	/**
	 * 此方法如果返回null，框架层面则不会发心跳；如果返回非null，框架层面会定时发本方法返回的消息包
	 */
	public HjPacket heartbeatPacket() {
		AjaxJson ajaxJson = new AjaxJson();
		try {
			heartbeatPacket.setBody(JSON.toJSONString(ajaxJson).getBytes("utf-8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return heartbeatPacket;
	}

	public static HjPacket getHeartbeatPacket() {
		return heartbeatPacket;
	}
}
